package com.github.codemperor.api.security;

import com.github.codemperor.api.*;
import com.github.codemperor.api.security.annotation.EmprApi;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.util.function.Consumer;

@Slf4j
public class ApiScan {

    /**
     * 用于回调
     */
    public Consumer function;

    /**
     * 处理crm的api
     *
     * @return
     */
    public ApiScan crm() {
        try {
            scanAllApiByInterface(ICrmApi.class, "CRM");
        } catch (Exception ex) {
            log.error("", ex);
        }
        return this;
    }

    /**
     * 处理frontend的api
     *
     * @return
     */
    public ApiScan frontend() {
        try {
            scanAllApiByInterface(IFrontendApi.class, "FRONTEND");
        } catch (Exception ex) {
            log.error("", ex);
        }
        return this;
    }


    /**
     * 处理FrontendAuthorized的api
     *
     * @return
     */
    public ApiScan frontendAuthorized() {
        try {
            scanAllApiByInterface(IFrontendAuthorizedApi.class, "FRONTEND_AUTHORIZED");
        } catch (Exception ex) {
            log.error("", ex);
        }
        return this;
    }

    /**
     * 处理inner的api
     *
     * @return
     */
    public ApiScan inner() {
        try {
            scanAllApiByInterface(IInnerApi.class, "INNER");
        } catch (Exception ex) {
            log.error("", ex);
        }
        return this;
    }

    /**
     * 处理open的api
     *
     * @return
     */
    public ApiScan open() {
        try {
            scanAllApiByInterface(IOpenApi.class, "OPEN");
        } catch (Exception ex) {
            log.error("", ex);
        }
        return this;
    }

    /**
     * 处理接口类中的信息。此接口开放，如果有更多的api接口类，可以参考上的那些写法,但需亚明确类型
     *
     * @param cls
     * @param type
     */
    public void scanAllApiByInterface(Class cls, String type) {
        Field[] fields = cls.getDeclaredFields(); //别用getName，会获取父类的字段
        for (Field f : fields) {
            try {
                f.setAccessible(true);

                Object uri = f.get(cls);
                EmprApi emprApi = f.getAnnotation(EmprApi.class);
                if (emprApi == null) {
                    log.error("{}, {} Annotation(EmprApi) is null", f.getName(), uri);
                    continue;
                }
                log.info("fieldName: {}, uri: {}, method: {}, desc: {}, module: {}, type: {}", f.getName(), uri, emprApi.method(), emprApi.desc(), emprApi.module().name(), type);
                if (null != function) {
                    function.accept(null); //这里可以入库或者做其他操作
                }
            } catch (Exception e) {
                log.error("", e);
            }
        }
    }
}
